/**
 * EntityManager - 实体管理器
 * 负责管理所有游戏实体的生命周期、更新和渲染
 */

import { Entity, EntityType } from './Entity'

export interface EntityManagerOptions {
  maxEntities?: number
  enableSpatialPartitioning?: boolean
}

export class EntityManager {
  private entities: Map<string, Entity> = new Map()
  private entitiesByType: Map<EntityType, Set<Entity>> = new Map()
  private entitiesToAdd: Entity[] = []
  private entitiesToRemove: string[] = []
  private maxEntities: number
  // Spatial partitioning feature (reserved for future use)
  // private enableSpatialPartitioning: boolean

  constructor(options: EntityManagerOptions = {}) {
    this.maxEntities = options.maxEntities || 1000
    // this.enableSpatialPartitioning = options.enableSpatialPartitioning || false
    
    // 初始化实体类型映射
    Object.values(EntityType).forEach(type => {
      this.entitiesByType.set(type, new Set())
    })
  }

  /**
   * 添加实体
   */
  addEntity(entity: Entity): void {
    if (this.entities.size >= this.maxEntities) {
      console.warn(`EntityManager: Maximum entities limit (${this.maxEntities}) reached`)
      return
    }

    if (this.entities.has(entity.id)) {
      console.warn(`EntityManager: Entity with id "${entity.id}" already exists`)
      return
    }

    this.entitiesToAdd.push(entity)
  }

  /**
   * 移除实体
   */
  removeEntity(id: string): void {
    if (!this.entities.has(id)) {
      console.warn(`EntityManager: Entity with id "${id}" not found`)
      return
    }

    this.entitiesToRemove.push(id)
  }

  /**
   * 根据实体对象移除
   */
  removeEntityByReference(entity: Entity): void {
    this.removeEntity(entity.id)
  }

  /**
   * 获取实体
   */
  getEntity(id: string): Entity | undefined {
    return this.entities.get(id)
  }

  /**
   * 根据类型获取实体
   */
  getEntitiesByType<T extends Entity>(type: EntityType): T[] {
    const entitySet = this.entitiesByType.get(type)
    return entitySet ? Array.from(entitySet) as T[] : []
  }

  /**
   * 获取所有实体
   */
  getAllEntities(): Entity[] {
    return Array.from(this.entities.values())
  }

  /**
   * 获取活跃实体数量
   */
  getEntityCount(): number {
    return this.entities.size
  }

  /**
   * 根据类型获取实体数量
   */
  getEntityCountByType(type: EntityType): number {
    const entitySet = this.entitiesByType.get(type)
    return entitySet ? entitySet.size : 0
  }

  /**
   * 更新所有实体
   */
  updateAll(deltaTime: number): void {
    // 处理待添加的实体
    this.processPendingAdditions()

    // 更新所有活跃实体
    for (const entity of this.entities.values()) {
      if (entity.active) {
        entity.update(deltaTime)
      }
    }

    // 清理需要移除的实体
    this.processPendingRemovals()
  }

  /**
   * 渲染所有实体
   */
  renderAll(ctx: CanvasRenderingContext2D): void {
    // 按类型顺序渲染，确保正确的层级关系
    const renderOrder = [
      EntityType.BACKGROUND,
      EntityType.COLLECTIBLE,
      EntityType.POWERUP,
      EntityType.OBSTACLE,
      EntityType.BOSS,
      EntityType.PROJECTILE,
      EntityType.PLAYER
    ]

    for (const type of renderOrder) {
      const entities = this.getEntitiesByType(type)
      for (const entity of entities) {
        if (entity.visible) {
          entity.render(ctx)
        }
      }
    }
  }

  /**
   * 清空所有实体
   */
  clear(): void {
    // 销毁所有实体
    for (const entity of this.entities.values()) {
      entity.destroy()
    }

    this.entities.clear()
    this.entitiesByType.forEach(set => set.clear())
    this.entitiesToAdd.length = 0
    this.entitiesToRemove.length = 0
  }

  /**
   * 根据条件查找实体
   */
  findEntities(predicate: (entity: Entity) => boolean): Entity[] {
    const result: Entity[] = []
    for (const entity of this.entities.values()) {
      if (predicate(entity)) {
        result.push(entity)
      }
    }
    return result
  }

  /**
   * 根据位置范围查找实体
   */
  findEntitiesInArea(x: number, y: number, width: number, height: number): Entity[] {
    return this.findEntities(entity => {
      return (
        entity.x < x + width &&
        entity.x + entity.width > x &&
        entity.y < y + height &&
        entity.y + entity.height > y
      )
    })
  }

  /**
   * 根据距离查找实体
   */
  findEntitiesInRadius(centerX: number, centerY: number, radius: number): Entity[] {
    const radiusSquared = radius * radius
    return this.findEntities(entity => {
      const center = entity.getCenter()
      const dx = center.x - centerX
      const dy = center.y - centerY
      return dx * dx + dy * dy <= radiusSquared
    })
  }

  /**
   * 处理待添加的实体
   */
  private processPendingAdditions(): void {
    for (const entity of this.entitiesToAdd) {
      this.entities.set(entity.id, entity)
      
      const typeSet = this.entitiesByType.get(entity.type)
      if (typeSet) {
        typeSet.add(entity)
      }
    }
    this.entitiesToAdd.length = 0
  }

  /**
   * 处理待移除的实体
   */
  private processPendingRemovals(): void {
    // 添加需要自动移除的实体
    for (const entity of this.entities.values()) {
      if (entity.shouldBeRemoved()) {
        this.entitiesToRemove.push(entity.id)
      }
    }

    // 移除实体
    for (const id of this.entitiesToRemove) {
      const entity = this.entities.get(id)
      if (entity) {
        // 从类型映射中移除
        const typeSet = this.entitiesByType.get(entity.type)
        if (typeSet) {
          typeSet.delete(entity)
        }
        
        // 销毁实体
        entity.destroy()
        
        // 从主映射中移除
        this.entities.delete(id)
      }
    }
    this.entitiesToRemove.length = 0
  }

  /**
   * 获取性能统计信息
   */
  getStats(): {
    totalEntities: number
    entitiesByType: Record<string, number>
    memoryUsage: string
  } {
    const entitiesByType: Record<string, number> = {}
    
    for (const [type, entitySet] of this.entitiesByType) {
      entitiesByType[type] = entitySet.size
    }

    return {
      totalEntities: this.entities.size,
      entitiesByType,
      memoryUsage: `${Math.round(this.entities.size * 0.1)}KB` // 粗略估算
    }
  }

  /**
   * 调试信息
   */
  debug(): void {
    const stats = this.getStats()
    console.group('EntityManager Debug Info')
    console.log('Total Entities:', stats.totalEntities)
    console.log('Entities by Type:', stats.entitiesByType)
    console.log('Memory Usage:', stats.memoryUsage)
    console.log('Pending Additions:', this.entitiesToAdd.length)
    console.log('Pending Removals:', this.entitiesToRemove.length)
    console.groupEnd()
  }
}